package Agent;

import java.util.Vector;

import org.rtscup.client.adk.Agent;
import org.rtscup.core.Building;
import org.rtscup.core.Entity;
import org.rtscup.core.Map;
import org.rtscup.core.Obstacle;
import org.rtscup.core.RealEntity;
import org.rtscup.core.Resource;
import org.rtscup.core.Unit;
import org.rtscup.core.VirtualEntity;
import org.rtscup.core.World;
import org.rtscup.core.id.TypeId;
import org.rtscup.core.util.function.FunctionOrder;
import org.rtscup.core.util.function.IsTypeObjectFn;
import org.rtscup.util.IDGenerator;

import Basic.Point;
import Basic.Tiles;

public class WalkerAgent extends Agent {
	
	private Point[] bestPath;
	private int index;
	private Point goal;
	
	public WalkerAgent(String name, String team, Point goal) {
		super(name,team,IDGenerator.generateID());
		this.goal = goal;
	}

	public void init() {
		
		Map map = (Map) this.getMemory().find(
				new IsTypeObjectFn(TypeId.TYPE_MAP), FunctionOrder.MAXIMIZE);
		
		Vector<Entity> entities = this.getMemory().getAll().getList();
		Vector<Obstacle> obstacles = new Vector<Obstacle>();
		//int minWidth = 999999;
		//int minHeight = 999999;
		for(int i = 0 ; i < entities.size() ; i++){
			Entity e = entities.get(i);
		    if(e.getType() == TypeId.TYPE_OBSTACLE){
		    	Obstacle o = (Obstacle) e;
		    	//if(o.getWidth()<minWidth) minWidth=o.getWidth();
		    	//if(o.getHeight()<minHeight) minHeight=o.getHeight();
		    	obstacles.add(o);
		    }
		}
		
		/*
		System.out.println("Obstacles:");
		for(int i = 0 ; i < obstacles.size() ; i++){
			Obstacle o = obstacles.get(i);
			System.out.println("Obstacle "+(i+1)+" -> "+o.getX()+","+o.getY()+","+o.getWidth()+","+o.getHeight());
		}System.out.println();
		*/
		
		Unit self = (Unit) this.getSelf();
		Point start = new Point(self.getX(),self.getY());
		
		//Tiles tiles = new Tiles(map.getWidth(),map.getHeight(),map.getWidth()/self.getWidth(),
		//		map.getHeight()/self.getHeight(),obstacles);
		//Vector<Point> vp = tiles.aStar(start,this.goal);
		//this.bestPath = new Point[vp.size()];
		//vp.copyInto(this.bestPath);
		//this.index = 0;
		
		/*
		System.out.println("Best Path");
		for(int i = 0 ; i < this.bestPath.size() ; i++){
			Point p = this.bestPath.get(i);
			System.out.println((i+1)+" -> "+p.getX()+","+p.getY()+" tile = "+this.tiles.getTile(p));
		} System.out.println();
		*/
	}

	public void act() {
		//double t1 = (System.currentTimeMillis());
		//System.out.println("Time Before = "+(System.currentTimeMillis()));
		this.game0();
		//double t2 = (System.currentTimeMillis());
		//System.out.println("Time After = "+(System.currentTimeMillis()));
		//System.out.println("Total Time = "+(t2-t1));
	}
	
	public void game0(){
		
		//double t1 = (System.currentTimeMillis());
		Unit self = (Unit) this.getSelf();
		//System.out.println("Initial Self -> "+self.getX()+" "+self.getY());
		//double t2 = (System.currentTimeMillis());
		//System.out.println("Unit init time = "+(t2-t1));
		
		if(this.index < this.bestPath.length){
			//double t3 = (System.currentTimeMillis());
			Point next = this.bestPath[this.index];
			//System.out.println("next -> "+next.getX()+" "+next.getY());
			//double t4 = (System.currentTimeMillis());
			//System.out.println("first if init time = "+(t4-t3));
			//double t5 = (System.currentTimeMillis());
			if(self.getX()==next.getX() && self.getY()==next.getY()) this.index++;
			//double t6 = (System.currentTimeMillis());
			//System.out.println("index incr time = "+(t6-t5));
			//double t7 = (System.currentTimeMillis());
			if(this.index < this.bestPath.length){
				next = this.bestPath[this.index];
				//System.out.println("late next -> "+next.getX()+" "+next.getY());
				this.move(next.getX(),next.getY(),self.getSpeed());
			}
			//double t8 = (System.currentTimeMillis());
			//System.out.println("move time = "+(t8-t7));
		}
		else if(!(self.getX()==this.goal.getX() && self.getY()==this.goal.getY())){
			//double t9 = (System.currentTimeMillis());
			this.move(this.goal.getX(),this.goal.getY(),self.getSpeed());
			//double t10 = (System.currentTimeMillis());
			//System.out.println("second if time = "+(t10-t9));
		}
		
	}

	public void senseChange(Entity entity) { }

	public void senseEntity(Entity oldEntity, Entity newEntity) { }

	public Agent clone() { 
		WalkerAgent result = new WalkerAgent(this.getName(),this.getTeam(),this.goal);
		result.setActive(this.isActive());
		result.setPolicy(this.getPolicy());
		return result;
	}

}